﻿/*
 * Copyright (c) 2011 Roberto García López
 * 
 * email: vcrobe@gmail.com
 * 
 * website: http://vcrobe.blogspot.com
 * 
 * project host: http://vectorGraphics.codeplex.com
 * 
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SlimDX;

namespace Ellipse
{
	public static class MathEx
	{
		#region Constants
		/// <summary>
		/// Pi / 180
		/// </summary>
		const double deg2Rad = Math.PI / 180;
		/// <summary>
		/// 180 / Pi
		/// </summary>
		const double rad2Deg = 180 / Math.PI;

		const int fuzzFactor = 1000;
		const double extendedResolution = 1e-19 * fuzzFactor;

		#endregion

		/// <summary>
		/// Compares a number with epsilon if this value is less or equal to epsilon it returns true
		/// </summary>
		/// <param name="a"></param>
		/// <param name="epsilon"></param>
		/// <returns></returns>
		public static bool IsZero(double a, double epsilon)
		{
			if (epsilon == 0)
				epsilon = extendedResolution;
			return Math.Abs(a) <= epsilon;
		}

		/// <summary>
		/// Returns a vector containing the greatest of each item of the vector
		/// </summary>
		/// <param name="v1"></param>
		/// <param name="v2"></param>
		public static Vector3 Maximum(Vector3 v1, Vector3 v2)
		{
			return new Vector3((v1.X > v2.X) ? v1.X : v2.X, (v1.Y > v2.Y) ? v1.Y : v2.Y, (v1.Z > v2.Z) ? v1.Z : v2.Z);
		}

		/// <summary>
		/// Returns a vector containing the greatest of each item of the vector
		/// </summary>
		/// <param name="v1"></param>
		/// <param name="v2"></param>
		public static Vector2 Maximum(Vector2 v1, Vector2 v2)
		{
			return new Vector2((v1.X > v2.X) ? v1.X : v2.X, (v1.Y > v2.Y) ? v1.Y : v2.Y);
		}

		public static double Maximum(double a, double b)
		{
			return (a > b) ? a : b;
		}

		public static double Maximum(double x, double y, double z)
		{
			if (x > y)
			{
				if (x > z)
					return x;
				else
					return z;
			}
			else
				if (y > z)
					return y;
				else
					return z;
		}

		/// <summary>
		/// Returns a vector containing the lesser of each item of the vector
		/// </summary>
		public static Vector3 Minimum(Vector3 v1, Vector3 v2)
		{
			return new Vector3((v1.X < v2.X) ? v1.X : v2.X, (v1.Y < v2.Y) ? v1.Y : v2.Y, (v1.Z < v2.Z) ? v1.Z : v2.Z);
		}

		/// <summary>
		/// Returns a vector containing the lesser of each item of the vector
		/// </summary>
		public static Vector2 Minimum(Vector2 v1, Vector2 v2)
		{
			return new Vector2((v1.X < v2.X) ? v1.X : v2.X, (v1.Y < v2.Y) ? v1.Y : v2.Y);
		}

		public static double Minimum(double a, double b)
		{
			return (a < b) ? a : b;
		}

		/// <summary>
		/// Compares two values ignoring a very small difference (epsilon) between them as the difference
		/// </summary>
		public static bool IsEqualTo(double a, double b, double epsilon)
		{
			if (epsilon == 0)
				epsilon = Maximum(Minimum(Math.Abs(a), Math.Abs(b)) * extendedResolution, extendedResolution);
			if (a > b)
				return (a - b) <= epsilon;
			else
				return (b - a) <= epsilon;
		}
	}
}
